﻿using QxFramework.Core;
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using GameMap;
using GameCombine;
namespace GameControl
{
    public class GameManager : ManagerBase<GameManager>
    {
        public bool OnEndLevel = false;
  //      UIBase openingUI = null;
        public string User = "";
        public override void InitModules()
        {
            base.InitModules();
            Add<DataModule<GameFunctionalData>>(new DataModule<GameFunctionalData>(), new DataTypePair { fileName = Data.Instance.UserName, dataType = DataType.LevelItemsInfo });
            Add<DataModule<GameSettingData>>(new DataModule<GameSettingData>(), new DataTypePair { fileName = Data.Instance.UserName, dataType = DataType.LevelItemsInfo });
            Add<ItemInstantiateManager>(new ItemInstantiateManager());
            Add<ItemFuncManager>(new ItemFuncManager(),Get<IDataModule<GameFunctionalData>>().GameData.FuncList);
            Add<ItemHealthManager>(new ItemHealthManager());
            MessageManager.Instance.Get<GameAction>().RegisterHandler(GameAction.OpenBenchUI, OpenBenchUI);
            MessageManager.Instance.Get<GameAction>().RegisterHandler(GameAction.QuitBenchUI, CloseBenchUI);
            MessageManager.Instance.Get<GameAction>().RegisterHandler(GameAction.EndCurrentLevel,EndCurrentLevel );
            MessageManager.Instance.Get<GameAction>().RegisterHandler(GameAction.ReturnToHome, ReturnToHome);
            MessageManager.Instance.Get<GameAction>().RegisterHandler(GameAction.Save, Save);
            MessageManager.Instance.Get<GameAction>().RegisterHandler(GameAction.Skip, Skip);
            OnEndLevel = false;
      //      MessageManager.Instance.Get<MusicMsg>().RegisterHandler(MusicMsg,);
        }
        public enum MusicMsg
        {
            BGM,Effect
        }
        EventArgs Skip(object sender, EventArgs e)
        {

            var lists = GameMapManager.Get<IMapManager>().FindAllPlayerItem();
            var obj = lists.Find(s => s.ItemName.StartsWith("Core"));
            if (obj == null)
            {
                UIManager.Instance.Open("DialogWindowUI", 5, args: new DialogWindowUI.DialogWindowUIArg
("注意", "核心已损坏\n请重新读档", null, "确定",null
          //   MessageManager.Instance.Get<GameControl.GameAction>().DispatchMessage(GameControl.GameAction.ReturnToHome, this, null);
      ));
                return null;
            }
            foreach (var x in lists)
            {

                MessageManager.Instance.Get<GameMap.ItemMapEvent>().DispatchMessage(GameMap.ItemMapEvent.MapToBench, this, new GameMap.ItemMapArgs
                {
                    ItemName = x.ItemName,
                    User = x.User
                });
            }
            MessageManager.Instance.Get<GameAction>().DispatchMessage(GameAction.EndCurrentLevel, this,immediate:false);
            return null;
        }
        EventArgs Save(object sender, EventArgs e)
        {

            Get<IDataModule<GameSettingData>>().GameData.NeedLoadFromScene = false;
            SetUserWithBench(Get<IDataModule<GameSettingData>>().GameData.UserWithBenchPairs);
            MessageManager.Instance.Get<ItemSyncMsg>().DispatchMessage(ItemSyncMsg.ForceClearExceptPosFixedItem, this);
            GameMapManager.Get<IDataManager>().SaveTo();
            AudioControl.Instance.PlaySound("Save");
            return null;
        }
        void SetUserWithBench(List<Tuple<string,Vector3Int>> list)
        {
            list.Clear();
            //暂时性的写法

            list.Add(CombineManager.Get<ICombineUIManager>().UserWithBenchPair);
        }
        EventArgs ReturnToHome(object sender, EventArgs e)
        {
          //  CombineManager.Get<ICombineUIManager>().CloseCombineBench();
            ProcedureManager.Instance.ChangeTo <TitleProcedure >();
            return null;
        }
        EventArgs EndCurrentLevel(object sender, EventArgs e)
        {
            OnEndLevel = true;
           // CombineManager.Get<ICombineUIManager>().CloseCombineBench();
            GameMapManager.Get<IMapManager>().DestoryAllItemOnScene();
            GameMapManager.Get<IDataModule<ItemsData>>().GameData.CurrentScene = LevelManager.Instance.NextLevel;
            Get<IDataModule<GameSettingData>>().GameData.NeedLoadFromScene = true;
            GameMapManager.Get<IDataManager>().SaveTo();
            if (LevelManager.Instance.CurrentLevel.StartsWith("Map"))
            {
                ProcedureManager.Instance.ChangeTo<SceneLoadProcedure>(new SceneLoadPair("End", typeof(EndProcedure)));
            }
            else
            {

                ProcedureManager.Instance.ChangeTo<SceneLoadProcedure>(new SceneLoadPair(LevelManager.Instance.NextLevel, typeof(GameProcedure)));
            }
            return null;
        }
        bool OpenUICheck(BenchArgs tp)
        {
            if (tp.interactItemName == null)
            {
                return true;
            }
            var field = Get<IItemInstantiateManager>().GetItemFieldByName(tp.interactItemName);
            /*if (field.User != this.User)
            {
                return false;
            }*/
           /* if (openingUI)
            {
                Debug.LogError("重复打开编辑界面");
                return false;
            }*/
            if (tp.collectedItems.Find(s => s.name == field.ItemName) == null)
            {
                //    Debug.LogError("没有找到打开编辑界面的物体");

                    UIManager.Instance.Open("DialogWindowUI", 5, args: new DialogWindowUI.DialogWindowUIArg
    ("注意", "没有找到打开编辑界面的物体", null, "确定", null));

            }
            return true;
        }
        EventArgs OpenBenchUI(object sender, EventArgs e)
        {
            var tp = e as BenchArgs;
            if (!OpenUICheck(tp))
            {
                return null;
            }
            
            string user = tp.user;
                //GameMap.GameMapManager.Get<IItemInstantiateManager>().GetItemFieldByName(tp.interactItemName).User;

            foreach(var x in tp.collectedItems)
            {

                MessageManager.Instance.Get<GameMap.ItemMapEvent>().DispatchMessage(GameMap.ItemMapEvent.MapToBench, this, new GameMap.ItemMapArgs
                {
                    ItemName=x.name,User=user
                });
            }
            CombineManager.Get<ICombineUIManager>().OpenCombineBench(new CombineUIArgs { user = user, benchName=tp.benchName});

            return null;
        }
        EventArgs CloseBenchUI(object sender, EventArgs e)
        {
            if (CloseUICheck((e as BenchArgs).user) == false)
            {
                return null;
            }
            CombineManager.Get<ICombineUIManager>().CloseCombineBench();
            var items = GameMapManager.Get<IBagManager>((e as BenchArgs).user).ItemsInBench;
            while(items.Count>0)
            {
                var x = items.Last<CombinableItemField>();
            //    x.MeshTransform.LocalRotate = x.MeshTransform.MeshRotate * 90;
                MessageManager.Instance.Get<ItemMapEvent>().DispatchMessage(ItemMapEvent.BenchToMap, this, new ItemMapArgs
                {
                    ItemName = x.ItemName,
                    MeshTransform= x.MeshTransform,
                    Position= CalcWorldPos(ClockManager.Get<IItemSyncManager>().GetGameObjectByName((e as BenchArgs).benchName).transform.position, x.MeshTransform.BenchMeshPos),
                    PhysicTransform = new ItemPhysicTransform
                    {
                        Angle = 0,
                        Velocity = Vector3.zero,
                        AngleVelocity=0,
               
                    }

                }, null,true);
            }
            MessageManager.Instance.Get<ItemSyncMsg>().DispatchMessage(ItemSyncMsg.ForceSync, this, null,null, true);
            return null;
        }
        Vector3 CalcWorldPos(Vector3 benchPos,Vector3Int itemPos)
        {
            Vector3Int Pos = itemPos;
            Vector3Int siz = CombineUIManager.combineTableSize;
            float length = MapManager.itemSize;
            Vector3 offset = new Vector3(0,-length/2,0);
            Vector3 ans = new Vector3(0, 0, Pos.z);
            Pos.x -= (siz.x+1) / 2;
            Pos.y -= (siz.y + 1) / 2;
            ans.x = Pos.x * length;
            if ((siz.x & 1) == 0)
            {
                ans.x -= length / 2f;
            }
            ans.y = Pos.y * length;
            if ((siz.y & 1) == 0)
            {
                ans.y -= length / 2f;
            }
            Debug.Log(ans + offset + benchPos);
            return ans + offset+benchPos;
        }
        bool CloseUICheck(string user)
        {
            //return true;
            var state=CombineManager.Get<IItemCombineManager>().GenItemJoint(
                GameMap.GameMapManager.Get<GameMap.IBagManager>().ItemsInBench
                );
            if (state == ItemLayoutState.Successfull)
            {
                return true;
            }
            else
            {
                if (state == ItemLayoutState.Overlapped)
                {
                    UIManager.Instance.Open("DialogWindowUI", 5, args: new DialogWindowUI.DialogWindowUIArg
("注意", "场上物体重叠", null, "确定", null));
                } 
                if (state == ItemLayoutState.CoreNotFound)
            {
                UIManager.Instance.Open("DialogWindowUI", 5, args: new DialogWindowUI.DialogWindowUIArg
("注意", "场上没有放置核心", null, "确定", null));
            }
            if (state == ItemLayoutState.CoreNotSetting)
            {
                UIManager.Instance.Open("DialogWindowUI", 5, args: new DialogWindowUI.DialogWindowUIArg
("注意", "场上核心的按键没有设置正确", null, "确定", null));
            }
                return false;
            }
           
        
   

            return true;
        }
        private void OnDrawGizmos()
        {
        //    Gizmos.DrawCube(MapManager.MapBounds.center,MapManager.MapBounds.size);
        }
        /*enum ItemStartCombineState
        {
            CoreNotFound,
            OtherCoreExist,

        }*/
    }
    public class GameFunctionalData : GameDataBase
    {
        public List<FuncField> FuncList = new List<FuncField>();



    }
    public class GameSettingData : GameDataBase
    {
        /// <summary>
        /// 可用的拼装台
        /// </summary>
        public List<string> UsableBenchList = new List<string>();
        /// <summary>
        /// 存档时用户处于哪个拼装台上
        /// </summary>
        public List<Tuple<string, Vector3Int>> UserWithBenchPairs = new List<Tuple<string, Vector3Int>>();
        public bool NeedLoadFromScene = true;
    }
    public enum GameAction
    {
        OpenBenchUI,
        QuitBenchUI,
        BeginCurrentLevel,
        EndCurrentLevel,
        ReturnToHome,
        Save,
        Skip,
    }
}

